package email

import (
	"crypto/tls"
	"fmt"
	"net/smtp"
	"strings"
)

// SMTPClient SMTP客户端结构体
type SMTPClient struct {
	Host     string
	Port     int
	Username string
	Password string
	Auth     smtp.Auth
}

// NewSMTPClient 创建SMTP客户端
func NewSMTPClient(host string, port int, username, password string) *SMTPClient {
	auth := smtp.PlainAuth("", username, password, host)
	return &SMTPClient{
		Host:     host,
		Port:     port,
		Username: username,
		Password: password,
		Auth:     auth,
	}
}

// SendMail 发送邮件
func (c *SMTPClient) SendMail(from, fromName string, to []string, subject, body string, isHTML bool) error {
	// 构建邮件头
	headers := make(map[string]string)
	headers["From"] = fmt.Sprintf("%s <%s>", fromName, from)
	headers["To"] = strings.Join(to, ",")
	headers["Subject"] = subject
	headers["MIME-Version"] = "1.0"

	if isHTML {
		headers["Content-Type"] = "text/html; charset=UTF-8"
	} else {
		headers["Content-Type"] = "text/plain; charset=UTF-8"
	}

	// 构建邮件内容
	message := ""
	for k, v := range headers {
		message += fmt.Sprintf("%s: %s\r\n", k, v)
	}
	message += "\r\n" + body

	// 发送邮件
	addr := fmt.Sprintf("%s:%d", c.Host, c.Port)

	// 如果是TLS端口，使用TLS连接
	if c.Port == 465 || c.Port == 587 {
		return c.sendMailTLS(addr, from, to, []byte(message))
	}

	return smtp.SendMail(addr, c.Auth, from, to, []byte(message))
}

// sendMailTLS 使用TLS发送邮件
func (c *SMTPClient) sendMailTLS(addr, from string, to []string, msg []byte) error {
	// 创建TLS连接
	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		ServerName:         c.Host,
	}

	conn, err := tls.Dial("tcp", addr, tlsConfig)
	if err != nil {
		return err
	}
	defer conn.Close()

	// 创建SMTP客户端
	client, err := smtp.NewClient(conn, c.Host)
	if err != nil {
		return err
	}
	defer client.Quit()

	// 认证
	if err = client.Auth(c.Auth); err != nil {
		return err
	}

	// 设置发件人
	if err = client.Mail(from); err != nil {
		return err
	}

	// 设置收件人
	for _, addr := range to {
		if err = client.Rcpt(addr); err != nil {
			return err
		}
	}

	// 发送邮件内容
	w, err := client.Data()
	if err != nil {
		return err
	}

	_, err = w.Write(msg)
	if err != nil {
		return err
	}

	return w.Close()
}
